package com.cetc.controller;

import com.cetc.model.HttpResult;
import com.cetc.model.MainData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.lang.reflect.Field;
import java.util.*;

/**
 * C-DRG的18个规则校验控制器
 * Created by Administrator on 2018/9/18.
 */
@Api(value = "StrokeCheckController", description = "Stroke的数据规则校验控制器")
@Controller
public class StrokeCheckController {

    /**
     * Stroke的数据规则校验
     * @param request 请求
     * @param response 响应
     * @param mainData 请求对象
     * @param bindingResult 字段校验信息
     * @return 校验结果
     * @throws Exception 异常
     */
    @ResponseBody
    @RequestMapping(value = "/check", method = RequestMethod.GET)
    @ApiOperation(value="规则校验", notes="C-DRG的18个规则校验")
    public Object CdrgCheck(HttpServletRequest request, HttpServletResponse response,
                            @Valid MainData mainData, BindingResult bindingResult) throws Exception {
        try {
            //返回信息
            List<HttpResult> list = new ArrayList<>();
            Map<String, Object> map = new HashMap<String, Object>();
            //字段校验----字段参数格式在封装进MainData的时候就会进行校验了，并将结果封装到BindingResult
            if(bindingResult.hasErrors()){
                //字段校验
                list = checkPara(bindingResult);
            }
            //校验未通过
            if (list.size() > 0) {
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("TOTAL", list.size());
                data.put("ROWS", list);

                map.put("CODE", "300");
                map.put("MESSAGE", "数据字段校验未通过");
                map.put("DATA", data);

                return map;
            //校验通过
            }else{
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("TOTAL", list.size());
                data.put("ROWS", list);

                map.put("CODE", "200");
                map.put("MESSAGE", "校验通过");
                map.put("DATA", data);
            }
            return map;
        }
        catch (Exception ex){
            //返回信息
            List<HttpResult> list = new ArrayList<>();
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("TOTAL", list.size());
            data.put("ROWS", list);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("CODE", "500");
            map.put("MESSAGE", "接口调用失败");
            map.put("DATA", data);

            return map;
        }
    }
    /**
     * 字段校验
     * @param bindingResult 校验信息
     * @return 验证结果
     * @throws Exception 异常
     */
    private List<HttpResult> checkPara(BindingResult bindingResult) throws Exception {
        //验证结果
        List<HttpResult> list = new ArrayList<>();

        //获取字段映射信息
        Map<String, String> map = getFieldInfo();

        List<ObjectError> objectErrors = bindingResult.getAllErrors();
        for(ObjectError objectError: objectErrors){
            HttpResult httpResult = new HttpResult();
            httpResult.setRULE("000");
            httpResult.setMSG("【" + map.get(((FieldError) objectError).getField()) + "】" + objectError.getDefaultMessage());
            list.add(httpResult);
        }
        return list;
    }
    /**
     * 获取字段映射信息
     * @return 字段映射表
     */
    private Map<String,String> getFieldInfo() {
        //字段映射表
        Map<String,String> map = new HashMap<>();

        //MainData字段信息
        Field[] fields = MainData.class.getDeclaredFields();
        for(Field f : fields) {
            ApiParam apiParam = f.getAnnotation(ApiParam.class);
            map.put(f.getName(), apiParam.value());
        }
        return map;
    }
}